package com.beiben.workflow.service.impl;

import com.beiben.common.GlobalConstant;
import com.beiben.utils.DateUtil;
import com.beiben.work.process.domain.FileProcessUser;
import com.beiben.work.process.mapper.FileProcessUserMapper;
import com.beiben.work.process.service.IFileProcessUserService;
import com.beiben.workflow.domain.*;
import com.beiben.workflow.mapper.WfApplyMapper;
import com.beiben.workflow.mapper.WfCheckMapper;
import com.beiben.workflow.service.IWfApplyService;
import com.beiben.workflow.service.IWfCheckLogService;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.exception.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * 工作流申请Service业务层处理
 *
 * @author 熊国强
 * @date 2020-12-17
 */
@Service
public class WfApplyServiceImpl implements IWfApplyService {

    @Autowired
    private WfApplyMapper wfApplyMapper;
    @Autowired
    private WfCheckMapper wfCheckMapper;

    @Autowired
    private IWfCheckLogService wfCheckLogService;

    @Autowired
    private IFileProcessUserService fileProcessUserService;
    @Autowired
    private FileProcessUserMapper fileProcessUserMapper;

    /**
     * 查询工作流申请
     *
     * @param applyId 工作流申请ID
     * @return 工作流申请
     */
    @Override
    public WfApply selectWfApplyById(Long applyId) {
        return wfApplyMapper.selectWfApplyById(applyId);
    }

    /**
     * 查询工作流申请列表
     *
     * @param wfApply 工作流申请
     * @return 工作流申请
     */
    @Override
    public List<WfApply> selectWfApplyList(WfApply wfApply) {
        return wfApplyMapper.selectWfApplyList(wfApply);
    }

    /**
     * 新增工作流申请
     *
     * @param wfApply 工作流申请
     * @return 结果
     */
    @Override
    public int insertWfApply(WfApply wfApply) {
        wfApply.setCreateTime(DateUtils.getNowDate());
        return wfApplyMapper.insertWfApply(wfApply);
    }

    /**
     * 修改工作流申请
     *
     * @param wfApply 工作流申请
     * @return 结果
     */
    @Override
    public int updateWfApply(WfApply wfApply) {
        wfApply.setUpdateTime(DateUtils.getNowDate());
        return wfApplyMapper.updateWfApply(wfApply);
    }

    /**
     * 批量删除工作流申请
     *
     * @param applyIds 需要删除的工作流申请ID
     * @return 结果
     */
    @Override
    public int deleteWfApplyByIds(Long[] applyIds) {
        return wfApplyMapper.deleteWfApplyByIds(applyIds);
    }

    /**
     * 删除工作流申请信息
     *
     * @param applyId 工作流申请ID
     * @return 结果
     */
    @Override
    public int deleteWfApplyById(Long applyId) {
        return wfApplyMapper.deleteWfApplyById(applyId);
    }

    /**
     * 提交申请 并插入审批流程
     *
     * @param wfApply
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, timeout = 72000, rollbackFor = Exception.class)
    public Long submitApplyCheck(WfApplyVo wfApply) {
        Long tableId = wfApply.getTableId();
        Long[] itemIds = {tableId};
        //验证上传材料
        fileProcessUserService.verifyAttachment(itemIds);
        //设置申请时间
        Date createTime = DateUtil.getNowDate();
        wfApply.setCreateTime(createTime);
        // 根据申请类型转换tableName
        String tableName;
        String applyType = wfApply.getApplyType();
        //表名转换
        //0 日常共工作 1 项目工作 都来自 work_file_process_user 表
        if ("0".equals(applyType) || "1".equals(applyType)) {
            tableName = GlobalConstant.WORK_FILE_PROCESS_USER;
        } else if ("2".equals(applyType)) {
            //2 来自 pm_project 表 项目节点工作
            //验证项目节点下 所有项目工作是否已审批完成
            FileProcessUser fileProcessUser = fileProcessUserMapper.selectFileProcessUserById(tableId);
            //查询未完成的工作数
            int isNotFinishedNum = fileProcessUserMapper.getFileProcessUserIsNotFinished(fileProcessUser.getWorkId());
            if (isNotFinishedNum > 0) {
                throw new BaseException("存在未完成的项目工作，请完成所有项目工作再提交审批！");
            }
            tableName = GlobalConstant.PM_PROJECT;
        } else {
            throw new BaseException("无该工作类型信息，无法查询附件！");
        }
        //验证是否提交申请
//        int count = wfCheckMapper.verifyApplyInfo(tableId, tableName);
        WfApply wa = wfApplyMapper.verifyApplyInfoByIdAndName(tableId, tableName);
        Long id = null;
        if (wa!=null) {
            WfCheck wfCheck = wfCheckMapper.selectWfCheckVoByApplyId(wa.getApplyId(),wa.getState());
            wa.setState(WorkFlowConstant.APPLY_STATE_CHECK);
            wa.setCompletion(wfApply.getCompletion());
            wfApplyMapper.updateWfApply(wa);
            wfCheck.setState(WorkFlowConstant.APPLY_STATE_CHECK);
            wfCheckMapper.updateWfCheck(wfCheck);
            id = wa.getApplyId();
//            throw new BaseException("该申请已提交，请勿重复提交！");
        }else{
            wfApply.setTableName(tableName);
            //保存申请
            wfApplyMapper.insertWfApplyRtId(wfApply);
            id = wfApply.getApplyId();
            //处理wfCheck.parentId
            List<WfCheck> checks = wfApply.getChecks();
            Long checkId = 0L;
            for (WfCheck check : checks) {
                check.setParentId(checkId);
                check.setState(WorkFlowConstant.APPLY_STATE_CHECK);
                check.setApplyId(id);
                check.setCreateTime(createTime);
                wfCheckMapper.insertWfCheckRtId(check);
                checkId = check.getCheckId();
            }
        }
        //提交申请 增加申请日志
        WfCheckLog log = new WfCheckLog();
        log.setApplyId(id);
        log.setState(WorkFlowConstant.APPLY_STATE_CHECK);
        log.setType(WorkFlowConstant.LOG_RECORD_TYPE_APPLY);
        log.setCreateTime(createTime);
        wfCheckLogService.insertWfCheckLog(log);
        return id;
    }

    @Override
    @DataScope(userAlias = "u")
    public List<WfApplyVo> applyList(WfApplyVo wfApply) {
        wfApply.setApplyUserId(SecurityUtils.getLoginUser().getUser().getUserId());
        List<WfApplyVo> wfApplyVos = wfApplyMapper.selecApplyList(wfApply);
        return wfApplyVos;
    }

    /**
     * 按申请id 修改申请状态
     *
     * @param applyId 申请id
     * @param state   状态
     * @return
     */
    @Override
    public int updateApplyState(Long applyId, String state) {
        WfApply wfApply = new WfApply();
        wfApply.setApplyId(applyId);
        wfApply.setState(state);
        wfApply.setUpdateTime(DateUtils.getNowDate());
        return wfApplyMapper.updateWfApply(wfApply);
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, timeout = 72000, rollbackFor = Exception.class)
    public int submit(Long userId, WfApply apply) {
        //校验 是否为打回
        WfCheck check = wfCheckMapper.verifyStateIsReturn(apply.getApplyId(), userId);
        if (check == null) {
            throw new RuntimeException("当前提交申请不合规，请查证后再试！");
        }
        apply.setState(WorkFlowConstant.APPLY_STATE_CHECK);
        apply.setUpdateTime(DateUtil.getNowDate());
        //提交申请 增加申请日志
        WfCheckLog log = new WfCheckLog();
        log.setApplyId(apply.getApplyId());
        log.setState(WorkFlowConstant.APPLY_STATE_CHECK);
        log.setType(WorkFlowConstant.LOG_RECORD_TYPE_APPLY);
        log.setCreateTime(DateUtils.getNowDate());
        wfCheckLogService.insertWfCheckLog(log);
        //修改check.state
        check.setState(WorkFlowConstant.APPLY_STATE_CHECK);
        wfCheckMapper.updateWfCheckState(check);
        return wfApplyMapper.submitApply(apply);
    }
}
